package view;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;

import common.Utils;

import model.DrawObject;

public class ViewRect extends ViewObject
{
	
	private Edge curEdge;
	
	
	
	
	public ViewRect(DrawObject obj, Graphics g)
	{
		super(obj, g);
	}

	public ViewRect(DrawObject obj, Graphics2D g2) 
	{
		super(obj, g2);
	}


	@Override
	public void Draw(Graphics g)
	{
		Graphics2D g2 = (Graphics2D)g;
		
		Color c = new Color(dObj.getRed(), dObj.getGreen(), dObj.getBlue());
		g2.setColor(c);
		
		if (dObj.getThickness() == 0)
		{
			g2.fillRect( dObj.getX1(), dObj.getY1(), dObj.getWidth(), dObj.getHeight());
		}
		else
		{
			g2.setStroke( new BasicStroke( (float)dObj.getThickness() ) );
			g2.drawRect( dObj.getX1(), dObj.getY1(), dObj.getWidth(), dObj.getHeight() );
		}
		
		super.Draw(g);
	}

	@Override
	public int pFuncX(double t)
	{
		int Ax = 0;
		int Bx = 0;
		
		switch (curEdge)
		{
			case TOP:
			case BOTTOM:
				Ax = dObj.getX1();
				Bx = Ax + dObj.getWidth() - 1;
				break;
			case RIGHT:
				Ax = dObj.getX1() + dObj.getWidth() - 1;
				Bx = Ax;
				break;
			case LEFT:
				Ax = dObj.getX1();
				Bx = Ax;
				break;
		}
		
		// Ax + t*(Bx - Ax ) 
		return (int)( Ax + t*(Bx - Ax) );
	}

	@Override
	public int pFuncY(double t)
	{
		int Ay = 0;
		int By = 0;
		
		switch (curEdge)
		{
			case TOP:
				Ay = dObj.getY1();
				By = Ay;
				break;
			case BOTTOM:
				Ay = dObj.getY1() + dObj.getHeight() - 1;
				By = Ay;
				break;
			case RIGHT:
			case LEFT:
				Ay = dObj.getY1();
				By = Ay + dObj.getHeight() - 1;
				break;
		}
		
		// Ay + t*(By - Ay)
		return (int)( Ay + t*(By - Ay) );
	}

	@Override
	public BoundBox getBounds(boolean padded)
	{
		int padding = (padded)? Utils.MIN_DIST : 0;
		
		BoundBox box = new BoundBox();
		
		box.setX( dObj.getX1() - padding );
		box.setY( dObj.getY1() - padding );
		box.setWidth( dObj.getWidth() + padding*2 - 1 );
		box.setHeight( dObj.getHeight() + padding*2 - 1 );
		
		return box;
	}

	@Override
	public boolean containsPoint(Point p)
	{
		if ( dObj.getThickness() == 0 )
		{
			if (this.getBounds(false).contains(p))
				return true;
			else 
				return false;
		}
		
		if ( !this.getBounds(true).contains(p) )
			return false;
		
		curEdge = Edge.TOP;
		int dist = this.distSqToShape(p);
		if (dist <= Utils.MIN_DIST_SQ)	return true;
		
		curEdge = Edge.BOTTOM;
		dist = this.distSqToShape(p);
		if (dist <= Utils.MIN_DIST_SQ)	return true;
		
		curEdge = Edge.RIGHT;
		dist = this.distSqToShape(p);
		if (dist <= Utils.MIN_DIST_SQ)	return true;
		
		curEdge = Edge.LEFT;
		dist = this.distSqToShape(p);
		if (dist <= Utils.MIN_DIST_SQ)	return true;
		
		
		return false;
	}

	
	private enum Edge
	{
		TOP, BOTTOM, RIGHT, LEFT
	}

	@Override
	public void deltaTranslatePoint(int pointNo, int dx, int dy)
	{
		
		switch (pointNo)
		{
		case 1:
			this.dObj.setX1( dObj.getX1() + dx );
			this.dObj.setY1( dObj.getY1() + dy );
			
			this.dObj.setX4( dObj.getX1() );
			this.dObj.setY2( dObj.getY1() );
			
			this.dObj.setWidth( this.dObj.getX3() - this.dObj.getX1() );
			this.dObj.setHeight( this.dObj.getY3() - this.dObj.getY1() );
			
			break;
		case 2:
			this.dObj.setX2( dObj.getX2() + dx );
			this.dObj.setY2( dObj.getY2() + dy );
			
			this.dObj.setY1( dObj.getY2() );
			this.dObj.setX3( dObj.getX2() );
			
			this.dObj.setWidth( this.dObj.getX2() - this.dObj.getX4() );
			this.dObj.setHeight( this.dObj.getY4() - this.dObj.getY2() );
			
			break;
		case 3:
			this.dObj.setX3( dObj.getX3() + dx );
			this.dObj.setY3( dObj.getY3() + dy );
			
			this.dObj.setY4( dObj.getY3() );
			this.dObj.setX2( dObj.getX3() );
			
			this.dObj.setWidth( this.dObj.getX3() - this.dObj.getX1() );
			this.dObj.setHeight( this.dObj.getY3() - this.dObj.getY1() );
			
			break;
		case 4:
			this.dObj.setX4( dObj.getX4() + dx );
			this.dObj.setY4( dObj.getY4() + dy );
			
			this.dObj.setY3( dObj.getY4() );
			this.dObj.setX1( dObj.getX4() );
			
			this.dObj.setWidth( this.dObj.getX2() - this.dObj.getX4() );
			this.dObj.setHeight( this.dObj.getY4() - this.dObj.getY2() );
			
			break;
		}
	}
	
	
	private int getSideLen(int a, int b)
	{
		return b-a+1;
	}
	
}
